package com.kingeid.framework.common.service;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import com.kingeid.framework.common.utils.SendMailUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;

 
public class MailSenderService {
	private String from;

	private String host;
	private String user;
	private String password;
	private String transportType;

	public String getFrom() {
		return from;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public String getHost() {
		return host;
	}

	public String getTransportType() {
		return transportType;
	}

	public void setTransportType(String transportType) {
		this.transportType = transportType;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * 发邮件
	 * 
	 * @param subject
	 *            邮件主题
	 * @param content
	 *            邮件内容
	 * @param attachFile
	 *            附件（多附件以;号分隔）
	 * @param from
	 *            发件人邮箱
	 * @param to
	 *            收件人邮箱（多收件人邮箱以;号分隔）
	 * @return boolean
	 */
	public boolean sendMail(String subject, String content, String attachFile,
			String from, String to) {

		final String from_ = from;
		final String[] to_ = to.split(";");
		final String subject_ = subject;
		final String content_ = content;
		final String[] paths = (attachFile == null || attachFile.trim() == "") ? new String[0]
				: attachFile.split(";");// 附件文件集合
		int len = paths.length;
		File[] files = new File[len];
		for (int i = 0; i < len; i++) {
			String p = paths[i];
			files[i] = new File(p);
		}
		return sendProcess(to_, subject_, from_, content_, files);

	}

	private boolean sendProcess(String[] to_, String subject_, String from_,
			String content_, File[] files) {
		Properties props = new Properties();
		// 设置发送邮件的邮件服务器的属性（这里使用网易的smtp服务器）
		props.put("mail.smtp.host", host);
		// 需要经过授权，也就是有户名和密码的校验，这样才能通过验证（一定要有这一条）
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.timeout", "25000");
		props.setProperty("mail.transport.protocol", transportType);
		Session session = Session.getDefaultInstance(props);
		session.setDebug(false);
		MimeMessage message = new MimeMessage(session);
		try {
			InternetAddress[] address = new InternetAddress[to_.length];
			for (int i = 0; i < to_.length; i++) {
				address[i] = new InternetAddress(to_[i]);
			}
			message.setRecipients(Message.RecipientType.TO, address);
			// 设置发信人
			message.setFrom(new InternetAddress(from_));
			// 设置主题
			message.setSubject(subject_, "UTF-8");
			Multipart mp = new MimeMultipart();
			// 向Multipart添加正文
			MimeBodyPart mbpContent = new MimeBodyPart();
			// mbpContent.setText(content_);
			// 发送网页内容
			mbpContent.setContent(content_, "text/html;charset=UTF-8");
			// 向MimeMessage添加（Multipart代表正文）
			mp.addBodyPart(mbpContent);
			// 向Multipart添加附件
			for (int i = 0; i < files.length; i++) {
				MimeBodyPart mbpFile = new MimeBodyPart();
				FileDataSource fds = new FileDataSource(files[i]);
				mbpFile.setDataHandler(new DataHandler(fds));
				mbpFile.setFileName(MimeUtility.encodeText(fds.getName()));
				mp.addBodyPart(mbpFile);
			}

			// 向Multipart添加MimeMessage
			message.setContent(mp);
			message.setSentDate(new Date());

			message.saveChanges();
			// 发送邮件

			Transport transport = session.getTransport(transportType);
			// 连接服务器的邮箱
			transport.connect(host, user, password);
			// 把邮件发送出去
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
			return true;
		} catch (UnsupportedEncodingException ue) {
			ue.printStackTrace();
			return false;
		} catch (SendFailedException se) {
			Address[] address = se.getInvalidAddresses();
			System.out.println("Invalid mails:");
			for (Address ad : address) {
				System.out.println(ad.toString());
			}
			return true;
		} catch (MessagingException me) {
			me.printStackTrace();
			
			return false;
		}
		 
	}

	/**
	 * 发邮件
	 * 
	 * @param subject
	 *            邮件主题
	 * @param content
	 *            邮件内容
	 * @param attachFile
	 *            附件（多附件以;号分隔）
	 * @param to
	 *            收件人邮箱（多收件人邮箱以;号分隔）
	 * @return boolean
	 */
	public boolean sendMail(String subject, String content, String attachFile,
			String to) {
		System.out.print("__TO_MAIL: " + to);
		boolean result = this.sendMail(subject, content, attachFile, from, to);
		return result;
	}
	
	public boolean sendFtlMail(String subject, String templatePath, Map<String, Object> map,String attachFile,
			String to) {
		System.out.print("__TO_MAIL: " + to);
		Template template = null;
		Configuration freeMarkerConfig = null;
		String content = "";
		try{
			freeMarkerConfig = new Configuration();
			freeMarkerConfig.setDirectoryForTemplateLoading(new File(
					getFilePath()));
			// 获取模板
			template = freeMarkerConfig.getTemplate(getFileName(templatePath),
					new Locale("Zh_cn"), "UTF-8");
			// 模板内容转换为string
			content = FreeMarkerTemplateUtils
					.processTemplateIntoString(template, map);
		}catch(Exception ex){
			ex.printStackTrace();
		}
		boolean result = this.sendMail(subject, content, attachFile, from, to);
		return result;
	}
	
	
	private static String getFilePath() {
		String path = getAppPath(SendMailUtil.class);
		path = path + File.separator + "mailtemplate" + File.separator;
		path = path.replace("\\", "/");
		System.out.println(path);
		return path;
	}

	private static String getFileName(String path) {
		path = path.replace("\\", "/");
		System.out.println(path);
		return path.substring(path.lastIndexOf("/") + 1);
	}

//	@SuppressWarnings("unchecked")
	public static String getAppPath(Class<?> cls) {
		// 检查用户传入的参数是否为空
		if (cls == null)
			throw new java.lang.IllegalArgumentException("参数不能为空！");
		ClassLoader loader = cls.getClassLoader();
		// 获得类的全名，包括包名
		String clsName = cls.getName() + ".class";
		// 获得传入参数所在的包
		Package pack = cls.getPackage();
		String path = "";
		// 如果不是匿名包，将包名转化为路径
		if (pack != null) {
			String packName = pack.getName();
			// 此处简单判定是否是Java基础类库，防止用户传入JDK内置的类库
			if (packName.startsWith("java.") || packName.startsWith("javax."))
				throw new java.lang.IllegalArgumentException("不要传送系统类！");
			// 在类的名称中，去掉包名的部分，获得类的文件名
			clsName = clsName.substring(packName.length() + 1);
			// 判定包名是否是简单包名，如果是，则直接将包名转换为路径，
			if (packName.indexOf(".") < 0)
				path = packName + "/";
			else {// 否则按照包名的组成部分，将包名转换为路径
				int start = 0, end = 0;
				end = packName.indexOf(".");
				while (end != -1) {
					path = path + packName.substring(start, end) + "/";
					start = end + 1;
					end = packName.indexOf(".", start);
				}
				path = path + packName.substring(start) + "/";
			}
		}
		// 调用ClassLoader的getResource方法，传入包含路径信息的类文件名
		java.net.URL url = loader.getResource(path + clsName);
		// 从URL对象中获取路径信息
		String realPath = url.getPath();
		// 去掉路径信息中的协议名"file:"
		int pos = realPath.indexOf("file:");
		if (pos > -1)
			realPath = realPath.substring(pos + 5);
		// 去掉路径信息最后包含类文件信息的部分，得到类所在的路径
		pos = realPath.indexOf(path + clsName);
		realPath = realPath.substring(0, pos - 1);
		// 如果类文件被打包到JAR等文件中时，去掉对应的JAR等打包文件名
		if (realPath.endsWith("!"))
			realPath = realPath.substring(0, realPath.lastIndexOf("/"));
		/*------------------------------------------------------------ 
		 ClassLoader的getResource方法使用了utf-8对路径信息进行了编码，当路径 
		  中存在中文和空格时，他会对这些字符进行转换，这样，得到的往往不是我们想要 
		  的真实路径，在此，调用了URLDecoder的decode方法进行解码，以便得到原始的 
		  中文及空格路径 
		-------------------------------------------------------------*/
		try {
			realPath = java.net.URLDecoder.decode(realPath, "utf-8");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		System.out.println("realPath----->" + realPath);
		return realPath;
	}

	/**
	 * 发邮件
	 * 
	 * @param subject
	 *            邮件主题
	 * @param content
	 *            邮件内容
	 * @param attachFile
	 *            附件
	 * @param from
	 *            发件人邮箱
	 * @param to
	 *            收件人邮箱（多收件人邮箱以;号分隔）
	 * @return boolean
	 */
	public boolean sendMail(String subject, String content, File[] attachFile,
			String from, String to) {

		final String from_ = from;
		final String[] to_ = to.split(";");
		final String subject_ = subject;
		final String content_ = content;
		final File[] files = attachFile;// 附件文件集合

		return sendProcess(to_, subject_, from_, content_, files);

	}

	/**
	 * 发邮件
	 * 
	 * @param subject
	 *            邮件主题
	 * @param content
	 *            邮件内容
	 * @param attachFile
	 *            附件
	 * @param to
	 *            收件人邮箱（多收件人邮箱以;号分隔）
	 * @return boolean
	 */
	public boolean sendMail(String subject, String content, File[] attachFile,
			String to) {
		boolean result = this.sendMail(subject, content, attachFile, from, to);
		return result;
	}
}
